package com.cyl.manager.act.service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.time.LocalDateTime;
import java.util.UUID;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cyl.manager.act.domain.entity.FhRechargeData;
import com.cyl.manager.act.domain.query.BatchGenerateRequest;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.cyl.manager.act.mapper.FhVipExchangeCodeMapper;
import com.cyl.manager.act.domain.entity.FhVipExchangeCode;
import com.cyl.manager.act.domain.query.FhVipExchangeCodeQuery;
import com.cyl.manager.act.domain.vo.H5FhInfoUser;
import com.cyl.manager.act.mapper.H5FhInfoUserMapper;
import com.ruoyi.common.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * VIP兑换码表Service业务层处理
 *
 *
 * @author zcc
 */
@Service
public class FhVipExchangeCodeService {
    private static final Logger log = LoggerFactory.getLogger(FhVipExchangeCodeService.class);
    
    @Autowired
    private FhVipExchangeCodeMapper fhVipExchangeCodeMapper;
    @Autowired
    private FhRechargeDataService fhRechargeDataService; // 直接注入
    @Autowired
    private H5FhInfoUserMapper fhInfoUserMapper;
    /**
     * 查询VIP兑换码表
     *
     * @param id VIP兑换码表主键
     * @return VIP兑换码表
     */
    public FhVipExchangeCode selectById(Long id) {
        return fhVipExchangeCodeMapper.selectById(id);
    }

    public void batchGenerate(BatchGenerateRequest request) {
        // 根据rechargeDataId获取VIP信息
        FhRechargeData templateRecharge = fhRechargeDataService.selectById(request.getRechargeDataId());
        if (templateRecharge == null) {
            throw new RuntimeException("未找到ID为" + request.getRechargeDataId() + "的充值模板");
        }

        List<FhVipExchangeCode> batchCodes = new ArrayList<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime expireTime = LocalDateTime.parse(request.getExpireTime(), formatter);

        // 批量创建记录
        for (int i = 0; i < request.getCount(); i++) {
            FhVipExchangeCode exchangeCode = new FhVipExchangeCode();
            // 复制模板信息
            exchangeCode.setRechargeDataId(templateRecharge.getId());
            exchangeCode.setVipType(templateRecharge.getType());
            exchangeCode.setVipDays(templateRecharge.getDay());
            exchangeCode.setOriginalPrice(templateRecharge.getPrice());
            exchangeCode.setDiscountPrice(templateRecharge.getDiscountPrice());
            exchangeCode.setExpireTime(expireTime);
            exchangeCode.setRemark(request.getRemark());
            exchangeCode.setStatus(0); // 默认状态为未使用
            exchangeCode.setCreateTime(LocalDateTime.now());
            exchangeCode.setCode(generateExchangeCode());
            batchCodes.add(exchangeCode);
        }
        // 批量保存
        this.insertBatch(batchCodes);
    }
    /**
     * 生成兑换码
     * @return 兑换码
     */
    private String generateExchangeCode() {
        // 生成随机兑换码的逻辑，例如UUID或自定义规则
        return UUID.randomUUID().toString().replace("-", "").toUpperCase().substring(0, 16);
    }
    /**
     * 批量新增VIP兑换码表
     *
     * @param fhVipExchangeCodes VIP兑换码表列表
     * @return 结果
     */
    public int insertBatch(List<FhVipExchangeCode> fhVipExchangeCodes) {
        int count = 0;
        for (FhVipExchangeCode code : fhVipExchangeCodes) {
            code.setCreateTime(LocalDateTime.now());
            count += fhVipExchangeCodeMapper.insert(code);
        }
        return count;
    }
    /**
     * 查询VIP兑换码表列表
     *
     * @param query 查询条件
     * @param page 分页条件
     * @return VIP兑换码表
     */
    public List<FhVipExchangeCode> selectList(FhVipExchangeCodeQuery query, Pageable page) {
        if (page != null) {
            PageHelper.startPage(page.getPageNumber() + 1, page.getPageSize());
        }
        QueryWrapper<FhVipExchangeCode> qw = new QueryWrapper<>();
        qw.eq("del_flag",0);
        String code = query.getCode();
        if (!StringUtils.isEmpty(code)) {
            qw.eq("code", code);
        }
        Long rechargeDataId = query.getRechargeDataId();
        if (rechargeDataId != null) {
            qw.eq("recharge_data_id", rechargeDataId);
        }
        String vipType = query.getVipType();
        if (!StringUtils.isEmpty(vipType)) {
            qw.eq("vip_type", vipType);
        }
        Integer vipDays = query.getVipDays();
        if (vipDays != null) {
            qw.eq("vip_days", vipDays);
        }
        BigDecimal originalPrice = query.getOriginalPrice();
        if (originalPrice != null) {
            qw.eq("original_price", originalPrice);
        }
        BigDecimal discountPrice = query.getDiscountPrice();
        if (discountPrice != null) {
            qw.eq("discount_price", discountPrice);
        }
        Integer status = query.getStatus();
        if (status != null) {
            qw.eq("status", status);
        }
        Long usedUserId = query.getUsedUserId();
        if (usedUserId != null) {
            qw.eq("used_user_id", usedUserId);
        }
        LocalDateTime usedTime = query.getUsedTime();
        if (usedTime != null) {
            qw.eq("used_time", usedTime);
        }
        LocalDateTime expireTime = query.getExpireTime();
        if (expireTime != null) {
            qw.eq("expire_time", expireTime);
        }
        return fhVipExchangeCodeMapper.selectList(qw);
    }

    /**
     * 新增VIP兑换码表
     *
     * @param fhVipExchangeCode VIP兑换码表
     * @return 结果
     */
    public int insert(FhVipExchangeCode fhVipExchangeCode) {
        fhVipExchangeCode.setCreateTime(LocalDateTime.now());
        return fhVipExchangeCodeMapper.insert(fhVipExchangeCode);
    }

    /**
     * 修改VIP兑换码表
     *
     * @param fhVipExchangeCode VIP兑换码表
     * @return 结果
     */
    public int update(FhVipExchangeCode fhVipExchangeCode) {
        return fhVipExchangeCodeMapper.updateById(fhVipExchangeCode);
    }

    /**
     * 批量删除VIP兑换码表
     *
     * @param ids 需要删除的VIP兑换码表主键
     * @return 结果
     */
    public int deleteByIds(Long[] ids) {
        return fhVipExchangeCodeMapper.updateDelFlagByIds(ids);
    }

    /**
     * 删除VIP兑换码表信息
     *
     * @param id VIP兑换码表主键
     * @return 结果
     */
    public int deleteById(Long id) {
        Long[] ids = {id};
        return fhVipExchangeCodeMapper.updateDelFlagByIds(ids);
    }
    /**
     * 兑换VIP码
     *
     * @param code 兑换码
     * @param userId 用户ID
     * @return 兑换结果
     */
    public String redeemVipCode(String code, Long userId) {
        try {
            // 1. 验证兑换码是否存在
            QueryWrapper<FhVipExchangeCode> qw = new QueryWrapper<>();
            qw.eq("code", code);
            qw.eq("del_flag", 0);
            FhVipExchangeCode exchangeCode = fhVipExchangeCodeMapper.selectOne(qw);
            
            if (exchangeCode == null) {
                return "兑换码不存在";
            }
            
            // 2. 检查兑换码状态
            if (exchangeCode.getStatus() != 0) { // 0表示未使用
                return "兑换码已被使用";
            }
            
            // 3. 检查兑换码是否过期
            if (exchangeCode.getExpireTime() != null && exchangeCode.getExpireTime().isBefore(LocalDateTime.now())) {
                return "兑换码已过期";
            }
            
            // 4. 查询用户信息
            H5FhInfoUser user = fhInfoUserMapper.selectFhInfoUserByUserId(userId);
            if (user == null) {
                return "用户不存在";
            }
            
            // 5. 更新用户VIP信息
            updateUserVipInfo(user, exchangeCode);
            
            // 6. 更新兑换码状态
            exchangeCode.setStatus(1); // 1表示已使用
            exchangeCode.setUsedUserId(userId);
            exchangeCode.setUsedTime(LocalDateTime.now());
            fhVipExchangeCodeMapper.updateById(exchangeCode);
            
            log.info("用户{}成功兑换VIP码{}，获得{}天VIP", userId, code, exchangeCode.getVipDays());
            return "兑换成功";
            
        } catch (Exception e) {
            log.error("兑换VIP码失败，用户ID：{}，兑换码：{}，错误：{}", userId, code, e.getMessage(), e);
            throw new ServiceException("兑换失败：" + e.getMessage());
        }
    }
    
    /**
     * 更新用户VIP信息
     *
     * @param user 用户信息
     * @param exchangeCode 兑换码信息
     */
    private void updateUserVipInfo(H5FhInfoUser user, FhVipExchangeCode exchangeCode) {
        try {
            // 记录原始状态用于日志
            Integer originalIsVip = user.getIsVip();
            Integer originalVipDays = user.getVipDays();
            LocalDateTime originalExpireTime = user.getVipExpireTime();
            
            user.setIsVip(1); // 设置为VIP
            
            // 累加VIP天数
            Integer currentVipDays = user.getVipDays() != null ? user.getVipDays() : 0;
            user.setVipDays(currentVipDays + exchangeCode.getVipDays());
            
            // 计算VIP到期时间 - 在原有基础上累加
            LocalDateTime expireTime;
            LocalDateTime now = LocalDateTime.now();
            
            if (user.getVipExpireTime() != null && user.getVipExpireTime().isAfter(now)) {
                // 如果用户当前VIP未过期，在原有到期时间基础上延长
                expireTime = user.getVipExpireTime().plusDays(exchangeCode.getVipDays());
            } else {
                // 如果用户VIP已过期或没有VIP，从当前时间开始计算
                expireTime = now.plusDays(exchangeCode.getVipDays());
            }
            
            user.setVipExpireTime(expireTime);
            user.setUpdateTime(LocalDateTime.now());
            
            // 执行更新操作，带重试机制
            int maxRetries = 3;
            for (int i = 0; i < maxRetries; i++) {
                try {
                    int updateResult = fhInfoUserMapper.updateFhInfoUser(user);
                    if (updateResult > 0) {
                        log.info("用户VIP信息更新成功，用户ID：{}，VIP状态: {} -> {}, VIP天数: {} -> {}, 到期时间: {} -> {}",
                                user.getId(), originalIsVip, user.getIsVip(),
                                originalVipDays, user.getVipDays(),
                                originalExpireTime, user.getVipExpireTime());
                        break;
                    } else {
                        log.warn("用户VIP信息更新失败，用户ID：{}，重试次数：{}", user.getId(), i + 1);
                        if (i == maxRetries - 1) {
                            throw new RuntimeException("用户VIP信息更新失败，已达到最大重试次数");
                        }
                    }
                } catch (Exception e) {
                    log.error("用户VIP信息更新异常，用户ID：{}，重试次数：{}，错误：{}", user.getId(), i + 1, e.getMessage());
                    if (i == maxRetries - 1) {
                        throw e;
                    }
                    // 等待一段时间后重试
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw new RuntimeException("更新用户VIP信息时被中断", ie);
                    }
                }
            }
        } catch (Exception e) {
            log.error("更新用户VIP信息失败，用户ID：{}，错误：{}", user.getId(), e.getMessage(), e);
            throw new RuntimeException("更新用户VIP信息失败：" + e.getMessage(), e);
        }
    }
}
